package com.zdp.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zdp.common.JsonUtils;
import com.zdp.domain.SkillGoods;
import com.zdp.mapper.SkillGoodsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author sesshomaru
 * @date 2021/7/24 21:28
 */
@Component
public class SkillGoodsService {

    @Autowired
    private RedisTemplate redisTemplate;
    public static final String SKILL_GOODS_PHONE = "SKILL_GOODS_PHONE";
    // 库存队列
    public static final String SKILL_GOODS_QUEUE = "SKILL_GOODS_QUEUE";
    @Autowired
    private SkillGoodsMapper skillGoodsMapper;

    /**
     * 每五秒执行一次 将需要参与秒杀的商品列表加载到缓存
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void prepareGood() {
        System.out.println("开始加载商品");
        // 获取所有已经在内存当中的商品ID列表 HASH结构
        Set<String> set = redisTemplate.boundHashOps(SKILL_GOODS_PHONE).keys();
        List<String> ids = new ArrayList<>();
        for (String id : set) {
            ids.add(id);
        }
        List<SkillGoods> list = null;
        // 只查询出不在内存当中的商品信息，并加载到内存
        QueryWrapper<SkillGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        queryWrapper.gt("num", 0);
        queryWrapper.gt("stock_count", 0);
        if (CollectionUtils.isEmpty(ids)) {
            list = skillGoodsMapper.selectList(queryWrapper);
        } else {
            queryWrapper.notIn("id", ids);
            list = skillGoodsMapper.selectList(queryWrapper);
        }
        if (!CollectionUtils.isEmpty(list)) {
            for (SkillGoods skillGood : list) {
                String json = JsonUtils.objectToJson(skillGood);
                redisTemplate.boundHashOps(SKILL_GOODS_PHONE).put(String.valueOf(skillGood.getId()), json);
                redisTemplate.boundListOps(SKILL_GOODS_QUEUE + skillGood.getId()).leftPushAll(convertToArray(skillGood.getStockCount(), skillGood.getId()));
            }
        }
        // 查看当前缓存中所有的商品信息
        Set<String> keys = redisTemplate.boundHashOps(SKILL_GOODS_PHONE).keys();
        for (String s : keys) {
            SkillGoods skillGoods = JsonUtils.jsonToPojo((String) redisTemplate.boundHashOps(SKILL_GOODS_PHONE).get(s), SkillGoods.class);
            System.out.println(skillGoods.getName() + " 库存剩余：" + skillGoods.getStockCount());
        }
    }

    // 创建一个和库存数量相同的数组(用于解决超卖)
    private Long[] convertToArray(Integer stockCount, Long id) {
        Long[] idsLong = new Long[stockCount];
        for (int i = 0; i < stockCount; i++) {
            idsLong[i] = id;
        }
        return idsLong;
    }

    /**
     * 提供查询商品信息的方法
     * @param productId 商品id
     * @return
     */
    public SkillGoods queryProduct(Long productId) {
        SkillGoods skillGoods = JsonUtils.jsonToPojo((String) redisTemplate.boundHashOps(SKILL_GOODS_PHONE).get(String.valueOf(productId)), SkillGoods.class);
        return skillGoods;
    }

    public void update(SkillGoods skillGoods) {
        skillGoodsMapper.updateById(skillGoods);
    }
}
